//
//  DFNetWorkMgr.m
//  DownGuys
//
//  Created by zhanghongwei on 1/12/16.
//  Copyright © 2016年 down-guys. All rights reserved.
//

#import "DFNetWorkMgr.h"
#import "AFNetworking.h"
#import "DFLog.h"


@implementation DFNetWorkMgr

+ (DFNetWorkMgr*)sharedInstance
{
    static DFNetWorkMgr *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //创建当前单例
        instance = [[DFNetWorkMgr alloc] init];
    });
    
    return instance;
}

#pragma mark - 网络请求，包含 “GET” 和 "POST" 方法
- (void)requestAsynchronous:(DFParamRequest*)params
                    success:(callSuccessBlock)success
                    failure:(callFailureBlock)failure
{
    NSString *method = params.method;
    if ([method isEqualToString:NetWork_Request_Type_GET]) {
        [self get:params success:success failure:failure];
    }
    else if ([method isEqualToString:NetWork_Request_Type_POST]) {
        [self post:params success:success failure:failure];
    }
    else if ([method isEqualToString:NetWork_Request_Type_DELET]) {
        [self delete:params success:success failure:failure];
    }
}


#pragma mark - GET
- (void)get:(DFParamRequest*)params success:(callSuccessBlock)success failure:(callFailureBlock)failure
{
    NSString *url = [params.url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//    NSInteger retryCount = params.retryCount;
//    NSDictionary *dicParams = params.dicParams;
//    NSDictionary *dicHeader = params.dicHeader;
    
    NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
    AFHTTPSessionManager *sessionMgr = [self creatSesionMgr:params.dicHeader];
    
    __weak __typeof(&*self)weakSelf = self;
    [sessionMgr GET:url parameters:params.dicParams progress:^(NSProgress * _Nonnull downloadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSTimeInterval endTime = [[NSDate date] timeIntervalSince1970];
        DLog(@"\n[API] %@ ,time:%fs ", url, endTime-startTime);
        [weakSelf callSuccess:task responseObject:responseObject success:success];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSTimeInterval endTime = [[NSDate date] timeIntervalSince1970];
        DLog(@"\n[API] %@ ,time:%fs", url, endTime-startTime);
        DLog(@"\n[API ERR] %@\nrequest failed with error:%@", url, error.localizedDescription);
        if (params.retryCount>0) {
            params.retryCount--;
            DLog(@"\n[API RETRY] %@ ,retry %ld times left", url, params.retryCount);
            [weakSelf get:params success:success failure:failure];
        }else {
            [weakSelf callFailure:task error:error failure:failure];
        }
    }];
    
}

#pragma mark - POST
- (void)post:(DFParamRequest*)params success:(callSuccessBlock)success failure:(callFailureBlock)failure;
{
    NSString *url = [params.url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
    AFHTTPSessionManager *sessionMgr = [self creatSesionMgr:params.dicHeader];
    
    __weak __typeof(&*self)weakSelf = self;
    [sessionMgr POST:url parameters:params.dicParams progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSTimeInterval endTime = [[NSDate date] timeIntervalSince1970];
        DLog(@"\n[API] %@ ,time:%fs ", url, endTime-startTime);
        [weakSelf callSuccess:task responseObject:responseObject success:success];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSTimeInterval endTime = [[NSDate date] timeIntervalSince1970];
        DLog(@"\n[API] %@ ,time:%fs", url, endTime-startTime);
        DLog(@"\n[API ERR] %@\nrequest failed with error:%@", url, error.localizedDescription);
        
        if (params.retryCount>0) {
            params.retryCount--;
            DLog(@"\n[API RETRY] %@ ,retry %ld times left", url, params.retryCount);
            [weakSelf post:params success:success failure:failure];
        }else {
            [weakSelf callFailure:task error:error failure:failure];
        }
    }];
    
}
#pragma mark - DELETE
- (void)delete:(DFParamRequest*)params success:(callSuccessBlock)success failure:(callFailureBlock)failure;
{
    NSString *url = [params.url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    AFHTTPSessionManager *sessionMgr = [self creatSesionMgr:params.dicHeader];
    __weak __typeof(&*self)weakSelf = self;
    
    [sessionMgr DELETE:url parameters:params.dicParams success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [weakSelf callSuccess:task responseObject:responseObject success:success];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (params.retryCount>0) {
            params.retryCount--;
            [weakSelf delete:params success:success failure:failure];
        }else {
            [weakSelf callFailure:task error:error failure:failure];
        }
    }];
}

#pragma mark - 网络请求头的设定
- (AFHTTPSessionManager*)creatSesionMgr:(NSDictionary*)dicHeader
{
    
    AFHTTPSessionManager *sessionMgr = [AFHTTPSessionManager manager];
    
    //请求设置
    //AFJSONRequestSerializer *request = [AFJSONRequestSerializer serializer];
    AFHTTPRequestSerializer *request = [AFHTTPRequestSerializer serializer];
    
    //设置 头部参数
    for (NSString *key in dicHeader.allKeys) {
        NSString *value = [dicHeader objectForKey:key];
        if (!value) {
            value = @"";
        }
        [request setValue:value forHTTPHeaderField:key];
    }
    
    //设置超时 时间
    request.timeoutInterval = NetWork_Request_TimeoutInterval;
    
    //返回设置
    //AFJSONResponseSerializer *response = [AFJSONResponseSerializer serializer];
    //response.removesKeysWithNullValues = YES;
    AFHTTPResponseSerializer *response = [AFHTTPResponseSerializer serializer];
    
    
    
    //如果报接受类型不一致请替换一致text/html或别的 (一般情况可不用添加)
    //response.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
    //response.acceptableContentTypes = [NSSet setWithObjects:@"text/html", @"application/json", @"text/json", @"text/javascript", nil];
    response.acceptableContentTypes = [NSSet setWithObjects:@"text/html", @"application/json", nil];
    
    //
    sessionMgr.requestSerializer = request;
    sessionMgr.responseSerializer = response;
    
    return sessionMgr;
}

#pragma mark - 网络回调
- (void)callSuccess:(NSURLSessionDataTask*)task responseObject:(id)responseObject success:(callSuccessBlock)success
{
    //根据status code的不同，做相应的处理
    NSHTTPURLResponse *response = (NSHTTPURLResponse*)task.response;
    NSInteger statusCode = response.statusCode;
    
    if (success) {
        success(statusCode, responseObject);
    }
}
- (void)callFailure:(NSURLSessionDataTask*)task error:(NSError*)error failure:(callFailureBlock)failure
{
    //根据status code的不同，做相应的处理
    NSHTTPURLResponse *response = (NSHTTPURLResponse*)task.response;
    NSInteger statusCode = response.statusCode;
    
    NSString *localizedDescription = [error localizedDescription];
    DLog(@"DFNetWorkMgr request error : %@\n", localizedDescription);
    
    //NSString *str = error.userInfo[@"com.alamofire.serialization.response.error.data"];
    NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"];
    NSString *errorStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    DLog(@"errorStr : \n%@", errorStr);
    statusCode = error.code;
    if (failure) {
        failure(statusCode, localizedDescription, errorStr);
    }
    
}



@end











